using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;
using System.Reflection;
namespace DbFramework.Data.ORM
{
    [Serializable]
    internal class ObjectSortComparer<T> : IComparer<T>
    {
        public static object GetPropertyValue(object obj, string propertyName)
        {
            if (obj == null)
            {
                throw new ArgumentNullException("obj");
            }

            Type objType = obj.GetType();
            PropertyInfo propertyInfo = objType.GetProperty(propertyName);
            if (propertyInfo == null)
            {
                throw new Exception("not find property");
            }

            return propertyInfo.GetValue(obj, null);
        }

        private string _propertyName;

        private ESortType _orderMode;

        public ObjectSortComparer(string propertyName, ESortType orderMode)
        {
            this._propertyName = propertyName;
            this._orderMode = orderMode;
        }

        public int Compare(T x, T y)
        {
            if ((x == null) && (y == null))
            {
                return 0;
            }
            else if ((x == null) && (y != null))
            {
                return (_orderMode == ESortType.ASC) ? -1 : 1;
            }
            else if ((x != null) && (y == null))
            {
                return (_orderMode == ESortType.ASC) ? 1 : -1;
            }
            else
            {
                object propertyDataX = GetPropertyValue(x, _propertyName);
                object propertyDataY = GetPropertyValue(y, _propertyName);

                if ((propertyDataX == null) && (propertyDataY == null))
                {
                    return 0;
                }
                else if ((propertyDataX == null) && (propertyDataY != null))
                {
                    return (_orderMode == ESortType.ASC) ? -1 : 1;
                }
                else if ((propertyDataX != null) && (propertyDataY == null))
                {
                    return (_orderMode == ESortType.ASC) ? 1 : -1;
                }
                else
                {
                    if (propertyDataX is IComparable)
                    {
                        int result = ((IComparable)propertyDataX).CompareTo(propertyDataY);
                        return (_orderMode == ESortType.ASC) ? result : -result;
                    }
                    else
                    {
                        return 0;
                    }
                }
            }
        }
    }
}
